﻿///////////////////////////////////////////////////////////////////////////////
//
//  This file is part of MathLib.NET.
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//  
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//  
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library;  If not, see 
//  <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////////

using System;
using ILNumerics;
using ILNumerics.BuiltInFunctions;

// Derivatives and Integrals
// =========================
//
// cumtrapz - Cumulative trapezoidal numerical integration 
// del2 - Discrete Laplacian 
// diff - Differences and approximate derivatives 
// gradient - Numerical gradient 
// polyder - Polynomial derivative 
// polyint - Integrate polynomial analytically 
// trapz - Trapezoidal numerical integration 

namespace MathLib
{
    /// <summary>
    /// Mathematical constants.
    /// </summary>
    public partial class MLMath
    {
        //
        // --- Differences and approximate derivatives ---
        //

        /// <summary>
        /// Compute differences between adjacent elements.
        /// </summary>
        /// <param name="arg">Matrix to compute differences from</param>
        /// <param name="n">Number of times to recursively compute differences</param>
        /// <param name="dim">Dimension to compute differences along</param>
        /// <returns>Matrix containing differences</returns>
        public static ILArray<double> diff(ILArray<double> arg, double n = 1, double dim = 1)
        {
            int ni = (int)n;
            int di = (int)dim;
            return ILMath.diff(arg, ni, di);
        }

        /// <summary>
        /// Compute differences between adjacent elements.
        /// </summary>
        /// <param name="arg">Matrix to compute differences from</param>
        /// <param name="n">Number of times to recursively compute differences</param>
        /// <param name="dim">Dimension to compute differences along</param>
        /// <returns>Matrix containing differences</returns>
        public static ILArray<float> diff(ILArray<float> arg, double n = 1, double dim = 1)
        {
            int ni = (int)n;
            int di = (int)dim;
            return ILMath.diff(arg, ni, di);
        }

        /// <summary>
        /// Compute differences between adjacent elements.
        /// </summary>
        /// <param name="arg">Matrix to compute differences from</param>
        /// <param name="n">Number of times to recursively compute differences</param>
        /// <param name="dim">Dimension to compute differences along</param>
        /// <returns>Matrix containing differences</returns>
        public static ILArray<double> diff(ILArray<int> arg, double n = 1, double dim = 1)
        {
            int ni = (int)n;
            int di = (int)dim;
            return ILMath.diff(ILMath.todouble(arg), ni, di);
        }

        /// <summary>
        /// Compute differences between adjacent elements.
        /// </summary>
        /// <param name="arg">Matrix to compute differences from</param>
        /// <param name="n">Number of times to recursively compute differences</param>
        /// <param name="dim">Dimension to compute differences along</param>
        /// <returns>Matrix containing differences</returns>
        public static ILArray<complex> diff(ILArray<complex> arg, double n = 1, double dim = 1)
        {
            int ni = (int)n;
            int di = (int)dim;
            return ILMath.diff(arg, ni, di);
        }

        /// <summary>
        /// Compute differences between adjacent elements.
        /// </summary>
        /// <param name="arg">Matrix to compute differences from</param>
        /// <param name="n">Number of times to recursively compute differences</param>
        /// <param name="dim">Dimension to compute differences along</param>
        /// <returns>Matrix containing differences</returns>
        public static ILArray<fcomplex> diff(ILArray<fcomplex> arg, double n = 1, double dim = 1)
        {
            int ni = (int)n;
            int di = (int)dim;
            return ILMath.diff(arg, ni, di);
        }

        /// <summary>
        /// Compute differences between adjacent elements.
        /// </summary>
        /// <param name="arg">Matrix to compute differences from</param>
        /// <param name="n">Number of times to recursively compute differences</param>
        /// <param name="dim">Dimension to compute differences along</param>
        /// <returns>Matrix containing differences</returns>
        public static ILArray<double> diff(ILArray<byte> arg, double n = 1, double dim = 1)
        {
            int ni = (int)n;
            int di = (int)dim;
            return ILMath.diff(ILMath.todouble(arg), ni, di);
        }

        /// <summary>
        /// Compute differences between adjacent elements.
        /// </summary>
        /// <param name="arg">Matrix to compute differences from</param>
        /// <param name="n">Number of times to recursively compute differences</param>
        /// <param name="dim">Dimension to compute differences along</param>
        /// <returns>Matrix containing differences</returns>
        public static ILArray<double> diff(ILArray<char> arg, double n = 1, double dim = 1)
        {
            int ni = (int)n;
            int di = (int)dim;
            return ILMath.diff(ILMath.todouble(arg), ni, di);
        }

        /// <summary>
        /// Compute differences between adjacent elements.
        /// </summary>
        /// <param name="arg">Matrix to compute differences from</param>
        /// <param name="n">Number of times to recursively compute differences</param>
        /// <param name="dim">Dimension to compute differences along</param>
        /// <returns>Matrix containing differences</returns>
        public static ILArray<double> diff(ILArray<long> arg, double n = 1, double dim = 1)
        {
            int ni = (int)n;
            int di = (int)dim;
            return ILMath.diff(ILMath.todouble(arg), ni, di);
        }

        /// <summary>
        /// Compute differences between adjacent elements.
        /// </summary>
        /// <param name="arg">Matrix to compute differences from</param>
        /// <param name="n">Number of times to recursively compute differences</param>
        /// <param name="dim">Dimension to compute differences along</param>
        /// <returns>Matrix containing differences</returns>
        public static ILArray<double> diff(ILArray<short> arg, double n = 1, double dim = 1)
        {
            int ni = (int)n;
            int di = (int)dim;
            return ILMath.diff(ILMath.todouble(arg), ni, di);
        }
    }
}
